package com.baitiaojun.video.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baitiaojun.api.domain.user.UserInfo;
import com.baitiaojun.api.domain.video.VideoChildComment;
import com.baitiaojun.api.domain.video.VideoComment;
import com.baitiaojun.api.exception.ConditionException;
import com.baitiaojun.api.util.AESUtil;
import com.baitiaojun.api.util.SnowFlakeUtil;
import com.baitiaojun.api.vo.PageInfo;
import com.baitiaojun.video.feign.ElasticsearchVideoFeign;
import com.baitiaojun.video.feign.UserFeign;
import com.baitiaojun.video.mapper.VideoCommentMapper;
import com.baitiaojun.video.service.VideoChildCommentService;
import com.baitiaojun.video.service.VideoService;
import com.baitiaojun.video.support.RedisSupport;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @类名 VideoChildCommentServiceImpl
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2023/3/7 16:23
 * @版本 1.0
 */
@Service
public class VideoChildCommentServiceImpl implements VideoChildCommentService {

    @Autowired
    private VideoService videoService;

    @Resource
    private VideoCommentMapper videoCommentMapper;

    @Autowired
    private ElasticsearchVideoFeign elasticsearchVideoFeign;

    @Autowired
    private UserFeign userFeign;

    @Override
    public void addChildVideoComment(VideoComment videoComment, Long userId) throws ConditionException {
        Long rootId = videoComment.getRootId();
        Long videoId = videoComment.getVideoId();
        if (ObjectUtils.isEmpty(rootId) || ObjectUtils.isEmpty(videoId)) {
            throw new ConditionException("参数异常");
        }
        Integer isExists = videoService.isExistsVideo(videoId);
        if (ObjectUtils.isEmpty(isExists)) {
            throw new ConditionException("该视频不存在");
        }
        VideoComment resVideoComment = elasticsearchVideoFeign.getParentVideoComment(rootId, videoId);
        if (ObjectUtils.isEmpty(videoComment)) {
            throw new ConditionException("该一级评论不存在");
        }
        Long id = SnowFlakeUtil.getNextId();
        Long replyUserId = resVideoComment.getUserId();
        Date date = new Date();
        videoComment.setId(id);
        videoComment.setUserId(userId);
        videoComment.setReplyUserId(replyUserId);
        videoComment.setCreateTime(date);
        int res = videoCommentMapper.insertSelective(videoComment);
        if (res == 0) {
            throw new ConditionException("二级评论添加到db失败");
        }
    }

    @Override
    public PageInfo getPageChildVideoCommentList(Integer pageNo, Integer pageSize, Long videoId, Long rootId) throws Exception {
        PageInfo pageInfo = elasticsearchVideoFeign.getPageChildVideoCommentList(pageNo, pageSize, videoId, rootId);
        Object pageList = pageInfo.getPageList();
        List<VideoChildComment> videoChildCommentList = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(pageList)) {
            videoChildCommentList = JSONObject.parseArray(JSONObject.toJSONString(pageList), VideoChildComment.class);
            Set<Long> userIds = videoChildCommentList.stream().map(VideoChildComment::getUserid).collect(Collectors.toSet());
            List<UserInfo> userInfoList = userFeign.batchGetUserInfoByUserIdsSet(userIds);
            AESUtil aesUtil = AESUtil.lazyGetAesUtil();
            for (UserInfo userInfo : userInfoList) {
                userInfo.setAvatar(aesUtil.encrypt(userInfo.getAvatar()));
            }
            //将userinfo列表转换成key为userid，value为userinfo的map集合
            Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getUserid, userInfo -> userInfo));
            for (VideoChildComment videoChildComment : videoChildCommentList) {
                Long userid = videoChildComment.getUserid();
                UserInfo userInfo = userInfoMap.get(userid);
                //过滤用户信息中不需要返回的字段
                userInfo.setGender(null);
                userInfo.setFollowed(null);
                userInfo.setUserid(null);
                userInfo.setSign(null);
                userInfo.setCreatetime(null);
                userInfo.setFollowing(null);
                //对二级评论通过userid拿到userinfo，childVideoComment中进行用户信息的设置，然后添加到二级评论列表
                videoChildComment.setUserInfo(userInfo);

            }
            for (VideoChildComment videoChildComment : videoChildCommentList) {
                videoChildComment.setUserid(null);
                videoChildComment.setReplyuserid(null);
                videoChildComment.setRootid(null);
            }
        }
        return PageInfo.builder().pageList(videoChildCommentList).size(pageInfo.getSize()).build();
    }

    @Override
    public void removeVideoChildComment(Long id, Long userId) throws ConditionException {
        Integer isExists = videoCommentMapper.isExistsById(id);
        if(ObjectUtils.isEmpty(isExists)) {
            throw new ConditionException("不存在此条二级评论");
        }
        int res = videoCommentMapper.deleteChildByIdAndUserId(id, userId);
        if (res == 0) {
            throw new ConditionException("删除此条二级评论失败");
        }
    }

    @Override
    public List<VideoChildComment> getReplayVideoCommentList(Long userId) throws Exception {
        List<VideoComment> videoCommentList = elasticsearchVideoFeign.getVideoCommentList(userId);
        Set<Long> ids = videoCommentList.stream().map(VideoComment::getId).collect(Collectors.toSet());
        List<VideoChildComment> videoChildCommentList = new ArrayList<>();
        if (ids.size() > 0) {
            //获取一级评论comment和一级评论userid的映射集
            Map<Long, String> commentMap = videoCommentList.stream().collect(Collectors.toMap(VideoComment::getId, VideoComment::getComment));
            Set<Map.Entry<Long, String>> entries = commentMap.entrySet();
            //获取当前用户的所有一级评论下的所有二级评论
            videoChildCommentList = elasticsearchVideoFeign.getVideoChildCommentList(ids);
            //如果当前用户下的二级评论不为空
            if (ObjectUtils.isNotEmpty(videoChildCommentList) && videoChildCommentList.size() > 0) {
                //得到所有二级评论的用户信息
                Set<Long> userIds = videoChildCommentList.stream().map(VideoChildComment::getUserid).collect(Collectors.toSet());
                List<UserInfo> userInfos = userFeign.batchGetUserInfoByUserIdsSet(userIds);
                //加密avatar
                AESUtil aesUtil = AESUtil.lazyGetAesUtil();
                for (UserInfo userInfo : userInfos) {
                    userInfo.setAvatar(aesUtil.encrypt(userInfo.getAvatar()));
                }
                //遍历所有二级评论进行赋值
                long count = 1;
                for (VideoChildComment videoChildComment : videoChildCommentList) {
                    videoChildComment.setReplyuserid(null);
                    //将当前二级评论进行userinfo关联
                    for (UserInfo userInfo : userInfos) {
                        if (videoChildComment.getUserid().equals(userInfo.getUserid())) {
                            userInfo.setCreatetime(null);
                            userInfo.setGender(null);
                            userInfo.setSign(null);
                            userInfo.setFollowing(null);
                            userInfo.setFollowed(null);
                            videoChildComment.setUserInfo(userInfo);
                        }
                        //如果是遍历最后一个二级评论，就把userid赋值为null
                        if (videoChildCommentList.size() == count) {
                            userInfo.setUserid(null);
                        }
                    }
                    //将当前二级评论进行一级comment关联
                    for (Map.Entry<Long, String> entry : entries) {
                        Long uId = entry.getKey();
                        if (uId.equals(videoChildComment.getRootid())) {
                            videoChildComment.setRootComment(entry.getValue());
                        }
                    }
                    //将不需要返回的值设置为null
                    videoChildComment.setRootid(null);
                    videoChildComment.setUserid(null);
                    count++;
                }
            }
        }
        return videoChildCommentList.stream().sorted(Comparator.comparing(VideoChildComment::getCreatetime)).collect(Collectors.toList());
    }
}
